﻿using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;

namespace M.Extensions
{
    /// <summary>
    /// ModelBuilder扩展，在table映射时，通过传递方法，改变映射内容
    /// </summary>
    public static class ModelBuilderExt
    {
        public static ModelBuilder TableMappingTo(this ModelBuilder modelBuilder,
    Func<IMutableEntityType, bool> verifyingEntityType,
    Func<string, string> tbleNameConvert,
    Func<string,string> colNameConvert)
        {
            foreach (var entityType in modelBuilder.Model.GetEntityTypes())
            {
                // 自定义实体校验，是否要对实体进行自定义处理
                //if (!verifyingEntityType(entityType))
                //{
                //    continue;
                //}

                var entityBuilder = modelBuilder.Entity(entityType.ClrType);

                // 表名处理
                {
                    // tblAnnotion.value 并不是特性的名称，而是内部综合优先级后，最终获得的名称
                    var tblAnnotion =entityBuilder.Metadata.FindAnnotation
                        (RelationalAnnotationNames.TableName);
                    // 按照优先级最终定义的表名，一般情况下使用这个就可以了
                    var annoTableName = entityBuilder.Metadata.GetTableName();
                    // 定义的类的类名
                    var clrTypeName = entityType.ClrType.Name;
                    // 与clrTypeName一般是一致的
                    var displayName=entityBuilder.Metadata.DisplayName();
                    // 以上代码作为笔记，供日后借鉴
                    

                    // 以下代码可以用于生产
                    // 获取表名，该方法足够
                    string tableName = entityBuilder.Metadata.GetTableName()??entityType.ClrType.Name;
                    // 处理表名称
                    entityBuilder.Metadata.SetTableName(tbleNameConvert(tableName));
                    //modelBuilder.Entity(entityType.Name).ToTable(tbleNameConvert(tableName));
                }


                foreach(var pt in entityType.GetProperties())
                {
                    // 处理列名
                    var colName=pt.GetColumnName();
                    pt.SetColumnName(colNameConvert(colName));

                    // 处理字符串类型列的默认长度
                    if (pt.ClrType == typeof(string) && !pt.GetMaxLength().HasValue)
                    {
                        pt.SetMaxLength(256);
                        pt.SetIsFixedLength(false);//false映射为nvarchar，true映射为nchar   
                    }
                }
            }

            return modelBuilder;
        }
    }
}
